package com.qth.valet.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qth.valet.common.annotation.Logs;
import com.qth.valet.common.annotation.RepeatSubmit;
import com.qth.valet.common.theadlocal.UserOrDriverIdHolder;
import com.qth.valet.common.utils.ResponseResult;
import com.qth.valet.common.utils.StatusConstants;
import com.qth.valet.entity.po.Driver;
import com.qth.valet.entity.po.DriverWithdraw;
import com.qth.valet.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;

@RestController
@RequiredArgsConstructor
@RequestMapping("/qth/withdraw")
public class DriverWithdrawController {

    private final DriversService driversService;

    private final DriverWithdrawService driverWithdrawService;

    @PostMapping("/withdraw")
    @Logs(operation = "司机提现")
    @RepeatSubmit
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> withdraw(@RequestBody Driver driver) {
        Integer driverId = UserOrDriverIdHolder.getDriverId();
        // 查询
        Driver dbDriver = driversService.getById(driverId);
        if (dbDriver == null) {
            throw new RuntimeException("参数异常");
        }
        Long balance = dbDriver.getAccountBalance();
        Long withdrawingBalance = dbDriver.getWithdrawingBalance();
        if (driver.getWithdrawAmount() > balance - withdrawingBalance) {
            return ResponseResult.fail("账户余额不足，请重新申请。");
        }
        // 创建一个提现信息
        DriverWithdraw driverWithdraw = new DriverWithdraw();
        driverWithdraw.setDriverId(driverId);
        driverWithdraw.setBankName(driver.getBankName());
        driverWithdraw.setBankCardId(driver.getBankCardId());
        driverWithdraw.setAmount(driver.getWithdrawAmount());
        driverWithdraw.setStatus(StatusConstants.DRIVER_WITHDRAW_WAIT);
        driverWithdraw.setApplyDate(LocalDateTime.now());
        driverWithdrawService.save(driverWithdraw);

        // 更新司机提现中金额
        LambdaUpdateWrapper<Driver> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Driver::getId, driverId);
        updateWrapper.setSql("withdrawing_balance = withdrawing_balance + " + driver.getWithdrawAmount());
        boolean update = driversService.update(updateWrapper);

        // 返回结果
        if (update) {
            return ResponseResult.success();
        } else {
            throw new RuntimeException("提现失败，请重试");
        }
    }

    /**
     * 司机查询提现分页
     */
    @GetMapping("/page")
    public ResponseResult<IPage<DriverWithdraw>> withdraw(@RequestParam(defaultValue = "1") int pageNum,
                                                          @RequestParam(defaultValue = "10") int pageSize) {
        LambdaQueryWrapper<DriverWithdraw> queryWrapper = new LambdaQueryWrapper<DriverWithdraw>()
                .eq(DriverWithdraw::getDriverId, UserOrDriverIdHolder.getDriverId())
                .orderByDesc(DriverWithdraw::getId);
        Page<DriverWithdraw> page = new Page<>(pageNum, pageSize);
        IPage<DriverWithdraw> list = driverWithdrawService.getBaseMapper().selectPage(page, queryWrapper);
        return ResponseResult.success(list);
    }

    /**
     * 司机取消提现
     */
    @PostMapping("/cancel/{withdrawId}")
    public ResponseResult<Void> cancel(@PathVariable Integer withdrawId) {
        boolean update = driverWithdrawService.update(new LambdaUpdateWrapper<DriverWithdraw>()
                .eq(DriverWithdraw::getId, withdrawId)
                .eq(DriverWithdraw::getStatus, StatusConstants.DRIVER_WITHDRAW_WAIT)
                .set(DriverWithdraw::getStatus, StatusConstants.DRIVER_WITHDRAW_CANCEL));
        if (!update) {
            throw new RuntimeException("参数异常");
        }
        return ResponseResult.success();
    }

}
